home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / Interfaces&Libraries / Universal / Interfaces / PInterfaces / DigitalSignature.p < prev    next >
Encoding:
Text File  |  1998-08-17  |  16.4 KB  |  386 lines  |  [TEXT/MPS ]

  1. {
  2.      File:        DigitalSignature.p
  3.  
  4.      Contains:    Digital Signature Interfaces.
  5.  
  6.      Version:    Technology:    AOCE toolbox 1.02
  7.                  Release:    Universal Interfaces 3.2
  8.  
  9.      Copyright:    © 1994-1998 by Apple Computer, Inc., all rights reserved.
  10.  
  11.      Bugs?:        For bug reports, consult the following page on
  12.                  the World Wide Web:
  13.  
  14.                      http://developer.apple.com/bugreporter/
  15.  
  16. }
  17. {$IFC UNDEFINED UsingIncludes}
  18. {$SETC UsingIncludes := 0}
  19. {$ENDC}
  20.  
  21. {$IFC NOT UsingIncludes}
  22.  UNIT DigitalSignature;
  23.  INTERFACE
  24. {$ENDC}
  25.  
  26. {$IFC UNDEFINED __DIGITALSIGNATURE__}
  27. {$SETC __DIGITALSIGNATURE__ := 1}
  28.  
  29. {$I+}
  30. {$SETC DigitalSignatureIncludes := UsingIncludes}
  31. {$SETC UsingIncludes := 1}
  32.  
  33. {$IFC UNDEFINED __MACTYPES__}
  34. {$I MacTypes.p}
  35. {$ENDC}
  36. {$IFC UNDEFINED __MIXEDMODE__}
  37. {$I MixedMode.p}
  38. {$ENDC}
  39. {$IFC UNDEFINED __FILES__}
  40. {$I Files.p}
  41. {$ENDC}
  42.  
  43.  
  44. {$PUSH}
  45. {$ALIGN MAC68K}
  46. {$LibExport+}
  47.  
  48. { values of SIGNameAttributeType }
  49.  
  50. CONST
  51.     kSIGCountryCode                = 0;
  52.     kSIGOrganization            = 1;
  53.     kSIGStreetAddress            = 2;
  54.     kSIGState                    = 3;
  55.     kSIGLocality                = 4;
  56.     kSIGCommonName                = 5;
  57.     kSIGTitle                    = 6;
  58.     kSIGOrganizationUnit        = 7;
  59.     kSIGPostalCode                = 8;
  60.  
  61.  
  62. TYPE
  63.     SIGNameAttributeType                = UInt16;
  64. Certificate status codes returned in SIGCertInfo or SIGSignerInfo from
  65. either SIGGetCertInfo or SIGGetSignerInfo respectively. kSIGValid means that
  66. the certificate is currently valid. kSIGPending means the certificate is
  67. currently not valid - but will be.  kSIGExpired means the certificate has
  68. expired. A time is always associated with a SIGCertStatus.  In each case the
  69. time has a specific interpretation.  When the status is kSIGValid the time is
  70. when the certificate will expire. When the status is kSIGPending the time is
  71. when the certificate will become valid. When the status is kSIGExpired the time
  72. is when the certificate expired. In the SIGCertInfo structure, the startDate
  73. and endDate fields hold the appropriate date information.  In the SIGSignerInfo
  74. structure, this information is provided in the certSetStatusTime field. In the
  75. SIGSignerInfo struct, the status time is actually represented by the SIGSignatureStatus
  76. field which can contain any of the types below. NOTE: The only time you will get 
  77. a kSIGInvalid status is when it pertains to a SIGSignatureStatus field and only when
  78. you get a signature that was created after the certificates expiration date, something
  79. we are not allowing on the Mac but that may not be restricted on other platforms. Also, 
  80. it will not be possible to get a kSIGPending value for SIGSignatureStatus on the Mac but
  81. possibly allowed by other platforms.
  82. }
  83. { Values for SIGCertStatus or SIGSignatureStatus }
  84.  
  85. CONST
  86.     kSIGValid                    = 0;                            {  possible for either a SIGCertStatus or SIGSignatureStatus  }
  87.     kSIGPending                    = 1;                            {  possible for either a SIGCertStatus or SIGSignatureStatus  }
  88.     kSIGExpired                    = 2;                            {  possible for either a SIGCertStatus or SIGSignatureStatus * possible only for a SIGSignatureStatus  }
  89.     kSIGInvalid                    = 3;
  90.  
  91.  
  92. TYPE
  93.     SIGCertStatus                        = UInt16;
  94.     SIGSignatureStatus                    = UInt16;
  95. { Number of bytes needed for a digest record when using SIGDigest }
  96.  
  97. CONST
  98.     kSIGDigestSize                = 16;
  99.  
  100.  
  101. TYPE
  102.     SIGDigestData                        = PACKED ARRAY [0..15] OF Byte;
  103.     SIGDigestDataPtr                    = ^Byte;
  104.     SIGCertInfoPtr = ^SIGCertInfo;
  105.     SIGCertInfo = RECORD
  106.         startDate:                UInt32;                                    {  cert start validity date  }
  107.         endDate:                UInt32;                                    {  cert end validity date  }
  108.         certStatus:                SIGCertStatus;                            {  see comment on SIGCertStatus for definition  }
  109.         certAttributeCount:        UInt32;                                    {  number of name attributes in this cert  }
  110.         issuerAttributeCount:    UInt32;                                    {  number of name attributes in this certs issuer  }
  111.         serialNumber:            Str255;                                    {  cert serial number  }
  112.     END;
  113.  
  114.     SIGSignerInfoPtr = ^SIGSignerInfo;
  115.     SIGSignerInfo = RECORD
  116.         signingTime:            UInt32;                                    {  time of signing  }
  117.         certCount:                UInt32;                                    {  number of certificates in the cert set  }
  118.         certSetStatusTime:        UInt32;                                    {  Worst cert status time. See comment on SIGCertStatus for definition  }
  119.         signatureStatus:        SIGSignatureStatus;                        {  The status of the signature. See comment on SIGCertStatus for definition }
  120.     END;
  121.  
  122.     SIGNameAttributesInfoPtr = ^SIGNameAttributesInfo;
  123.     SIGNameAttributesInfo = RECORD
  124.         onNewLevel:                BOOLEAN;
  125.         filler1:                BOOLEAN;
  126.         attributeType:            SIGNameAttributeType;
  127.         attributeScript:        ScriptCode;
  128.         attribute:                Str255;
  129.     END;
  130.  
  131.     SIGContextPtr                        = Ptr;
  132.     SIGSignaturePtr                        = Ptr;
  133. {
  134. Certificates are always in order. That is, the signers cert is always 0, the
  135. issuer of the signers cert is always 1 etc… to the number of certificates-1.
  136. You can use this constant for readability in your code.
  137. }
  138.  
  139. CONST
  140.     kSIGSignerCertIndex            = 0;
  141.  
  142. {
  143. Call back procedure supplied by developer, return false to cancel the current
  144. process.
  145. }
  146.  
  147. TYPE
  148. {$IFC TYPED_FUNCTION_POINTERS}
  149.     SIGStatusProcPtr = FUNCTION: BOOLEAN;
  150. {$ELSEC}
  151.     SIGStatusProcPtr = ProcPtr;
  152. {$ENDC}
  153.  
  154.     SIGStatusUPP = UniversalProcPtr;
  155.  
  156. CONST
  157.     uppSIGStatusProcInfo = $00000010;
  158.  
  159. FUNCTION NewSIGStatusProc(userRoutine: SIGStatusProcPtr): SIGStatusUPP;
  160.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  161.     INLINE $2E9F;
  162.     {$ENDC}
  163.  
  164. FUNCTION CallSIGStatusProc(userRoutine: SIGStatusUPP): BOOLEAN;
  165.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  166.     INLINE $205F, $4E90;
  167.     {$ENDC}
  168. {
  169. Resource id's of standard signature icon suite, all sizes and colors are available.
  170. }
  171.  
  172. CONST
  173.     kSIGSignatureIconResID        = -16797;
  174.     kSIGValidSignatureIconResID    = -16799;
  175.     kSIGInvalidSignatureIconResID = -16798;
  176.  
  177. { ——————————————————————————————— CONTEXT CALLS ——————————————————————————————— 
  178. To use the Digital Signature toolbox you will need a SIGContextPtr.  To create
  179. a SIGContextPtr you simply call SIGNewContext and it will create and initialize
  180. a context for you.  To free the memory occupied by the context and invalidate
  181. its internal data, call SIGDisposeContext. An initialized context has no notion
  182. of the type of operation it will be performing however, once you call
  183. SIGSignPrepare SIGVerifyPrepare, or SIGDigestPrepare, the contexts operation
  184. type is set and to switch  to another type of operation will require creating a
  185. new context. Be sure to pass the same context to corresponding toolbox calls
  186. (ie SIGSignPrepare, SIGProcessData, SIGSign)  in other words mixing lets say
  187. signing and verify calls with the same context is not allowed.
  188. }
  189. FUNCTION SIGNewContext(VAR context: SIGContextPtr): OSErr;
  190.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  191.     INLINE $203C, $0002, $076C, $AA5D;
  192.     {$ENDC}
  193. FUNCTION SIGDisposeContext(context: SIGContextPtr): OSErr;
  194.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  195.     INLINE $203C, $0002, $076D, $AA5D;
  196.     {$ENDC}
  197.  
  198. { ——————————————————————————————— SIGNING CALLS ——————————————————————————————— 
  199. Once you have created a SIGContextPtr, you create a signature by calling
  200. SIGSignPrepare once, followed by n calls to SIGProcessData, followed by one call
  201. toRcpt SIGSign. To create another signature on different data but for the same
  202. signer, don't dispose of the context and call SIGProcessData for the new data
  203. followed by a call SIGSign again. In this case the signer will not be prompted
  204. for their signer and password again as it was already provided.  Once you call
  205. SIGDisposeContext, all signer information will be cleared out of the context and
  206. the signer will be re-prompted.  The signer file FSSpecPtr should be set to nil
  207. if you want the toolbox to use the last signer by default or prompt for a signer
  208. if none exists.  The prompt parameter can be used to pass a string to be displayed
  209. in the dialog that prompts the user for their password.  If the substring "^1"
  210. (without the quotes) is in the prompt string, then the toolbox will replace it
  211. with the name of the signer from the signer selected by the user.  If an empty
  212. string is passed, the following default string will be sent to the toolbox
  213. "\pSigning as ^1.".  You can call any of the utility routines after SIGSignPrepare
  214. or SIGSign to get information about the signer or certs.
  215. }
  216. FUNCTION SIGSignPrepare(context: SIGContextPtr; {CONST}VAR signerFile: FSSpec; prompt: Str255; VAR signatureSize: Size): OSErr;
  217.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  218.     INLINE $203C, $0008, $076E, $AA5D;
  219.     {$ENDC}
  220. FUNCTION SIGSign(context: SIGContextPtr; signature: SIGSignaturePtr; statusProc: SIGStatusUPP): OSErr;
  221.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  222.     INLINE $203C, $0006, $076F, $AA5D;
  223.     {$ENDC}
  224.  
  225. { ——————————————————————————————— VERIFYING CALLS ——————————————————————————————— 
  226. Once you have created a SIGContextPtr, you verify a signature by calling
  227. SIGVerifyPrepare  once, followed by n calls to SIGProcessData, followed by one
  228. call to SIGVerify. Check the return code from SIGVerify to see if the signature
  229. verified or not (noErr is returned on  success otherwise the appropriate error
  230. code).  Upon successfull verification, you can call any of the utility routines
  231. toRcpt find out who signed the data.
  232. }
  233. FUNCTION SIGVerifyPrepare(context: SIGContextPtr; signature: SIGSignaturePtr; signatureSize: Size; statusProc: SIGStatusUPP): OSErr;
  234.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  235.     INLINE $203C, $0008, $0770, $AA5D;
  236.     {$ENDC}
  237. FUNCTION SIGVerify(context: SIGContextPtr): OSErr;
  238.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  239.     INLINE $203C, $0002, $0771, $AA5D;
  240.     {$ENDC}
  241. { —————————————————————————————— DIGESTING CALLS —————————————————————————————— 
  242. Once you have created a SIGContextPtr, you create a digest by calling
  243. SIGDigestPrepare once, followed by n calls to SIGProcessData, followed by one
  244. call to SIGDigest.  You can dispose of the context after SIGDigest as the
  245. SIGDigestData does not reference back into it.  SIGDigest returns the digest in
  246. digest.
  247. }
  248. FUNCTION SIGDigestPrepare(context: SIGContextPtr): OSErr;
  249.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  250.     INLINE $203C, $0002, $0772, $AA5D;
  251.     {$ENDC}
  252. FUNCTION SIGDigest(context: SIGContextPtr; VAR digest: SIGDigestData): OSErr;
  253.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  254.     INLINE $203C, $0004, $0773, $AA5D;
  255.     {$ENDC}
  256.  
  257. { —————————————————————————————— PROCESSING DATA —————————————————————————————— 
  258. To process data during a digest, sign, or verify operation call SIGProcessData
  259. as many times as necessary and with any sized blocks of data.  The data needs to
  260. be processed in the same order during corresponding sign and verify operations
  261. but does not need to be processed in the same sized chunks (i.e., the toolbox
  262. just sees it as a continuous bit stream).
  263. }
  264. FUNCTION SIGProcessData(context: SIGContextPtr; data: UNIV Ptr; dataSize: Size): OSErr;
  265.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  266.     INLINE $203C, $0006, $0774, $AA5D;
  267.     {$ENDC}
  268.  
  269. { ——————————————————————————————— UTILITY CALLS ——————————————————————————————— 
  270. Given a context that has successfully performed a verification SIGShowSigner
  271. will  display a modal dialog with the entire distinguished name of the person
  272. who signed the data. the prompt (if supplied) will appear at the top of the
  273. dialog.  If no prompt is specified, the default prompt "\pVerification
  274. Successfull." will appear.
  275.  
  276. Given a context that has been populated by calling SIGSignPrepare, SIGSign or a
  277. successful SIGVerify, you can make the remaining utility calls:
  278.  
  279. SIGGetSignerInfo will return the SignerInfo record.  The certCount can be used
  280. toRcpt index into the certificate set when calling SIGGetCertInfo,
  281. SIGGetCertNameAttributes or SIGGetCertIssuerNameAttributes. The signingTime is
  282. only defined if the call is made after SIGSign  or SIGVerify. The certSetStatus
  283. will tell you the best status of the entire certificate set while
  284. certSetStatusTime will correspond to the time associated with that status (see
  285. definitions above).
  286.  
  287. SIGGetCertInfo will return the SIGCertInfo record when given a valid index into
  288. the cert set in  certIndex.  Note: The cert at index kSIGSignerCertIndex is
  289. always the signers certificate.  The  serial number, start date and end date
  290. are there should you wish to display that info.  The  certAttributeCount and
  291. issuerAttributeCount provide the number of parts in the name of that certificate
  292. or that certificates issuer respectively.  You use these numbers to index into
  293. either SIGGetCertNameAttributes or SIGGetCertIssuerNameAttributes to retrieve
  294. the name. The certStatus will tell you the status of the certificate while
  295. certStatusTime will correspond to the time associated with that status (see
  296. definitions above).
  297.  
  298. SIGGetCertNameAttributes and SIGGetCertIssuerNameAttributes return name parts
  299. of the certificate at  certIndex and attributeIndex.  The newLevel return value
  300. tells you wether the name attribute returned is at the same level in the name
  301. hierarchy as the previous attribute.  The type return value tells you  the type
  302. of attribute returned. nameAttribute is the actual string containing the name
  303. attribute.   So, if you wanted to display the entire distinguished name of the
  304. person who's signature was just validated you could do something like this;
  305.  
  306.     (…… variable declarations and verification code would preceed this sample ……)
  307.  
  308.     error = SIGGetCertInfo(verifyContext, kSIGSignerCertIndex, &certInfo);
  309.     HandleErr(error);
  310.  
  311.     for (i = 0; i <= certInfo.certAttributeCount-1; i++)
  312.         (
  313.         error = SIGGetCertNameAttributes(
  314.             verifyContext, kSIGSignerCertIndex, i, &newLevel, &type, theAttribute);
  315.         HandleErr(error);
  316.         DisplayNamePart(theAttribute, type, newLevel);
  317.         )
  318. }
  319. FUNCTION SIGShowSigner(context: SIGContextPtr; prompt: Str255): OSErr;
  320.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  321.     INLINE $203C, $0004, $0775, $AA5D;
  322.     {$ENDC}
  323. FUNCTION SIGGetSignerInfo(context: SIGContextPtr; VAR signerInfo: SIGSignerInfo): OSErr;
  324.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  325.     INLINE $203C, $0004, $0776, $AA5D;
  326.     {$ENDC}
  327. FUNCTION SIGGetCertInfo(context: SIGContextPtr; certIndex: UInt32; VAR certInfo: SIGCertInfo): OSErr;
  328.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  329.     INLINE $203C, $0006, $0777, $AA5D;
  330.     {$ENDC}
  331. FUNCTION SIGGetCertNameAttributes(context: SIGContextPtr; certIndex: UInt32; attributeIndex: UInt32; VAR attributeInfo: SIGNameAttributesInfo): OSErr;
  332.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  333.     INLINE $203C, $0008, $0778, $AA5D;
  334.     {$ENDC}
  335. FUNCTION SIGGetCertIssuerNameAttributes(context: SIGContextPtr; certIndex: UInt32; attributeIndex: UInt32; VAR attributeInfo: SIGNameAttributesInfo): OSErr;
  336.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  337.     INLINE $203C, $0008, $0779, $AA5D;
  338.     {$ENDC}
  339.  
  340.  
  341. { ——————————————————————————— FILE SIGN & VERIFY CALLS —————————————————————————— 
  342. These calls allow you to detect the presence of a standard signtaure in a file as 
  343. well as sign and verify files in a standard way.  An example of this is the Finder, 
  344. which uses these calls to allow the user to "drop sign" a file.
  345.  
  346. To detect if a file is signed in the standard way, pass the FSSpec of the file to SIGFileIsSigned.
  347. A result of noErr means the file is in fact signed, otherwise, a kSIGNoSignature error will
  348. be returned.
  349.  
  350. Once you have created a SIGContextPtr, you can make calls to either sign or verify a file in
  351. a standard way: 
  352.  
  353. To sign a file, call SIGSignPrepare followed by 'n' number of calls to SIGSignFile,
  354. passing it the file spec for each file you wish to sign in turn.  You supply the context, the signature 
  355. size that was returned from SIGSignPrepare and an optional call back proc.  The call will take care of all
  356. the processing of data and affixing the signature to the file. If a signature already exists in the file, 
  357. it is replaced with the newly created signature.
  358.  
  359. To verify a file that was signed using SIGSignFile, call SIGVerifyFile passing it a new context and 
  360. the file spec.  Once this call has completed, if the verification is successfull, you can pass the context 
  361. to SIGShowSigner to display the name of the person who signed the file.
  362. }
  363. FUNCTION SIGFileIsSigned({CONST}VAR fileSpec: FSSpec): OSErr;
  364.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  365.     INLINE $203C, $0002, $09C4, $AA5D;
  366.     {$ENDC}
  367. FUNCTION SIGSignFile(context: SIGContextPtr; signatureSize: Size; {CONST}VAR fileSpec: FSSpec; statusProc: SIGStatusUPP): OSErr;
  368.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  369.     INLINE $203C, $0008, $09C5, $AA5D;
  370.     {$ENDC}
  371. FUNCTION SIGVerifyFile(context: SIGContextPtr; {CONST}VAR fileSpec: FSSpec; statusProc: SIGStatusUPP): OSErr;
  372.     {$IFC TARGET_OS_MAC AND TARGET_CPU_68K AND NOT TARGET_RT_MAC_CFM}
  373.     INLINE $203C, $0006, $09C6, $AA5D;
  374.     {$ENDC}
  375. {$ALIGN RESET}
  376. {$POP}
  377.  
  378. {$SETC UsingIncludes := DigitalSignatureIncludes}
  379.  
  380. {$ENDC} {__DIGITALSIGNATURE__}
  381.  
  382. {$IFC NOT UsingIncludes}
  383.  END.
  384. {$ENDC}
  385.